# -*- coding:utf-8 -*-
# @FileName : app\utils\service_checker.py
# @Time     : 2025/11/28
# @Author   : 天空之城
"""
服务检查工具模块

提供后端和前端服务启动状态检查功能
"""
#!/usr/bin/env python3
# -*- coding: utf-8 -*-


import socket
import subprocess
import time
import sys
import os


def check_port_availability(host: str, port: int, timeout: int = 1) -> bool:
    """
    检查指定端口是否可用（是否被占用）
    
    参数:
        host: 主机地址
        port: 端口号
        timeout: 连接超时时间（秒）
    
    返回:
        bool: 端口被占用返回True，否则返回False
    """
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(timeout)
        result = sock.connect_ex((host, port))
        sock.close()
        return result == 0
    except Exception as e:
        print(f"检查端口 {host}:{port} 时出错: {e}")
        return False


def wait_for_service_start(process: subprocess.Popen, port: int, service_name: str, 
                          max_wait_time: int = 30, wait_interval: int = 1) -> bool:
    """
    等待服务启动完成
    
    参数:
        process: 进程对象
        port: 服务端口号
        service_name: 服务名称（用于日志输出）
        max_wait_time: 最大等待时间（秒）
        wait_interval: 等待间隔（秒）
    
    返回:
        bool: 服务启动成功返回True，否则返回False
    """
    waited_time = 0
    
    while waited_time < max_wait_time:
        time.sleep(wait_interval)
        waited_time += wait_interval
        
        # 检查进程是否还在运行
        if process.poll() is not None:
            print(f"{service_name}启动失败，进程已退出")
            # 读取错误输出
            stdout, stderr = process.communicate()
            if stderr:
                print(f"错误信息: {stderr}")
            return False
        
        # 检查端口是否被占用（表示服务已启动）
        if check_port_availability('localhost', port):
            print(f"{service_name}启动成功！")
            return True
    
    print(f"{service_name}启动超时，可能启动失败")
    return False


def check_process_output(process: subprocess.Popen) -> tuple:
    """
    检查进程输出
    
    参数:
        process: 进程对象
    
    返回:
        tuple: (stdout, stderr) 进程的标准输出和错误输出
    """
    try:
        stdout, stderr = process.communicate(timeout=1)
        return stdout, stderr
    except subprocess.TimeoutExpired:
        # 进程仍在运行，返回空字符串
        return "", ""


def is_process_running(process: subprocess.Popen) -> bool:
    """
    检查进程是否仍在运行
    
    参数:
        process: 进程对象
    
    返回:
        bool: 进程正在运行返回True，否则返回False
    """
    return process.poll() is None


def terminate_process(process: subprocess.Popen, timeout: int = 5) -> bool:
    """
    终止进程
    
    参数:
        process: 进程对象
        timeout: 等待终止的超时时间（秒）
    
    返回:
        bool: 成功终止返回True，否则返回False
    """
    if process and is_process_running(process):
        process.terminate()
        try:
            process.wait(timeout=timeout)
            return True
        except subprocess.TimeoutExpired:
            process.kill()
            return True
    return False